package system

import (
	"atools/models"
	"atools/utils"
	"bytes"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

type MacosInfo struct {
}

func (macos MacosInfo) GetInstalledApps(app *App) []models.InstalledApp {
	var allApps []models.InstalledApp
	
	// 扫描用户应用目录
	userApps := macos.scanAppsInDirectory("/Applications", app)
	allApps = append(allApps, userApps...)
	
	// 扫描系统应用目录
	systemApps := macos.scanAppsInDirectory("/System/Applications", app)
	allApps = append(allApps, systemApps...)
	
	println("成功加载应用总数:", len(allApps))
	
	// 检查是否包含特殊应用
	for _, installedApp := range allApps {
		if installedApp.Name == "微信" || installedApp.Name == "计算器" || installedApp.Name == "Calculator" {
			println("找到特殊应用:", installedApp.Name, "路径:", installedApp.Path)
		}
	}
	
	return allApps
}

// scanAppsInDirectory 扫描指定目录中的应用
func (macos MacosInfo) scanAppsInDirectory(directory string, app *App) []models.InstalledApp {
	cmd := exec.Command("find", directory, "-name", "*.app", "-maxdepth", "2", "-type", "d")
	var out bytes.Buffer
	cmd.Stdout = &out
	err := cmd.Run()
	if err != nil {
		println("扫描目录失败:", directory, err.Error())
		return []models.InstalledApp{}
	}

	var apps []models.InstalledApp
	lines := strings.Split(strings.TrimSpace(out.String()), "\n")
	
	println("在", directory, "找到的应用文件数量:", len(lines))
	
	for _, line := range lines {
		line = strings.TrimSpace(line)
		if line == "" || !strings.HasSuffix(line, ".app") {
			continue
		}
		
		// 提取应用名称
		baseName := filepath.Base(line)
		appName := strings.TrimSuffix(baseName, ".app")
		
		// 跳过空名称
		if appName == "" {
			continue
		}
		
		iconOutputPath := appName + ".png"

		// 异步提取图标，不阻塞应用加载
		if app.BaseDir != "" {
			go func(appPath, outputPath string) {
				err := extractIcon(appPath, filepath.Join(app.BaseDir, "app_icons", outputPath))
				if err != nil {
					println("提取图标失败:", appPath, err.Error())
				}
			}(line, iconOutputPath)
		}

		// 创建应用信息
		// 对于特殊应用名称，提供中文别名
		var enName string
		var displayName string
		
		switch appName {
		case "WeChat":
			enName = "weixin"  // 微信的拼音
			displayName = "微信" // 显示中文名
		case "Calculator":
			enName = "jisuanqi" // 计算器的拼音
			displayName = "计算器" // 显示中文名
		case "Calendar":
			enName = "rili" // 日历的拼音
			displayName = "日历" // 显示中文名
		case "Mail":
			enName = "youjian" // 邮件的拼音
			displayName = "邮件" // 显示中文名
		case "Safari":
			enName = "liulanqi" // 浏览器的拼音
			displayName = "Safari浏览器" // 显示中文名
		case "Notes":
			enName = "beiwanglu" // 备忘录的拼音
			displayName = "备忘录" // 显示中文名
		case "Finder":
			enName = "fangdaqi" // 访达的拼音
			displayName = "访达" // 显示中文名
		default:
			enName = utils.GetPingYin(appName)
			displayName = appName
		}
		
		installedApp := models.InstalledApp{
			Name:    displayName,
			Path:    line,
			EnName:  enName,
			AppType: "InstallApp",
			Icon:    iconOutputPath,
		}
		
		apps = append(apps, installedApp)
		
		// 输出系统应用的调试信息
		if strings.HasPrefix(line, "/System/Applications") || len(apps) <= 5 {
			println("加载应用:", displayName, "路径:", line)
		}
	}
	
	return apps
}

// extractIcon 从 macOS .app 文件中提取图标并保存为 PNG 格式
func extractIcon(appPath string, outputPath string) error {
	// 创建输出目录
	outputDir := filepath.Dir(outputPath)
	cmd := exec.Command("mkdir", "-p", outputDir)
	err := cmd.Run()
	if err != nil {
		println("创建目录失败")
		return err
	}

	// 检查输出文件是否已存在，避免重复提取
	if _, err := os.Stat(outputPath); err == nil {
		return nil // 文件已存在，跳过提取
	}

	// 方法1: 尝试找到具体的 icns 文件
	resourcesDir := filepath.Join(appPath, "Contents", "Resources")
	if _, err := os.Stat(resourcesDir); err == nil {
		// 查找 icns 文件
		cmd := exec.Command("find", resourcesDir, "-name", "*.icns", "-type", "f")
		var out bytes.Buffer
		cmd.Stdout = &out
		err := cmd.Run()
		if err == nil {
			icnsFiles := strings.Split(strings.TrimSpace(out.String()), "\n")
			for _, icnsFile := range icnsFiles {
				if icnsFile != "" {
					// 使用 sips 转换第一个找到的 icns 文件
					cmd = exec.Command("sips", "-s", "format", "png", "-Z", "64", icnsFile, "--out", outputPath)
					err = cmd.Run()
					if err == nil {
						return nil // 成功提取
					}
				}
			}
		}
	}

	// 方法2: 使用 iconutil 提取应用图标
	cmd = exec.Command("iconutil", "-c", "png", "--output", outputPath, appPath)
	err = cmd.Run()
	if err == nil {
		return nil
	}

	// 方法3: 使用 qlmanage 生成缩略图
	cmd = exec.Command("qlmanage", "-t", "-s", "64", "-o", outputDir, appPath)
	err = cmd.Run()
	if err == nil {
		// qlmanage 生成的文件名格式为 appname.png
		qlOutputPath := filepath.Join(outputDir, filepath.Base(appPath)+".png")
		if _, err := os.Stat(qlOutputPath); err == nil {
			// 重命名为目标文件名
			return os.Rename(qlOutputPath, outputPath)
		}
	}

	// 如果所有方法都失败，创建一个占位符文件
	return os.WriteFile(outputPath, []byte{}, 0644)
}
